package com.dimeng.utils;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.ref.SoftReference;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;
import java.util.UUID;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnFocusChangeListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.LayoutParams;
import android.webkit.URLUtil;
import android.webkit.WebView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.dimeng.R;
import com.dimeng.TaojindiActivity;
import com.dimeng.entity.CropOption;
import com.dimeng.entity.Version;
import com.dimeng.service.DownloadService;
import com.google.gson.Gson;

@SuppressLint("SetJavaScriptEnabled")
public class CommonUtil {
	private static boolean isFirstTimeLoadBitmap = true;
	private static boolean isFirstTimeLoadTxt = true;
	private static long imgCacheContentLen = 0L;
	public static long txtCacheContentLen = 0L;

	/**
	 * @param activity
	 * @param promptDialog
	 * @return 检测网络状态
	 */
	public static boolean checkNetWorkStatus(final Activity activity,
			boolean promptDialog) {
		boolean netSataus = false;
		ConnectivityManager cwjManager = (ConnectivityManager) activity
				.getSystemService(Context.CONNECTIVITY_SERVICE);

		if (cwjManager.getActiveNetworkInfo() != null) {
			netSataus = cwjManager.getActiveNetworkInfo().isAvailable();
		}

		if (!netSataus && promptDialog) {
			Toast.makeText(activity, Constant.NET_ERROR, Toast.LENGTH_LONG)
					.show();
		}
		return netSataus;
	}

	/**
	 * 退出系统的对话框
	 * 
	 * @param activity
	 */
	public static void exitDialog(final Activity activity) {
		AlertDialog.Builder builder = new Builder(activity);
		builder.setMessage("确定退出吗?");
		// builder.setTitle("标题");
		builder.setPositiveButton("确定",
				new android.content.DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						Intent intent = new Intent(activity,
								TaojindiActivity.class);
						intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
						intent.putExtra("exit", true);
						activity.startActivity(intent);
					}
				});
		builder.setNegativeButton("取消",
				new android.content.DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						dialog.cancel();
					}
				});
		builder.create().show();
	}

	/**
	 * 退出当前视图
	 * 
	 * @param activity
	 */
	public static void exit(Activity activity) {
		activity.finish();
		System.exit(0);
	}

	/**
	 * 使用WebView加载url地址
	 * 
	 * @param context
	 *            视图上下文
	 * @param url
	 *            需访问的url
	 * @param webView
	 *            浏览器对像<br>
	 *            浏览器对像默认显示整个页面的边界,支持javascript、支持放大缩小、隐藏放大缩小工具
	 */
	public static void loadUrl(Context context, String url, WebView webView) {
		loadUrl(context, url, webView, true, true, true, true);
	}

	/**
	 * 使用WebView加载url地址
	 * 
	 * @param context
	 *            视图上下文
	 * @param url
	 *            需访问的url
	 * @param webView
	 *            浏览器对像
	 * @param jsEnabled
	 *            浏览器是否支持javascript
	 * @param supportZoom
	 *            浏览器是否支持放大缩小
	 * @param zoomControls
	 *            浏览器是否显示放大缩小工具
	 * @param isOverView
	 *            是否显示整个页面
	 */
	public static void loadUrl(Context context, String url, WebView webView,
			boolean jsEnabled, boolean supportZoom, boolean zoomControls,
			boolean isOverView) {
		webView.getSettings().setJavaScriptEnabled(jsEnabled);
		webView.getSettings().setSupportZoom(supportZoom);
		webView.getSettings().setBuiltInZoomControls(zoomControls);// 放大缩小工具条，如果屏幕支持多点触摸，则可以不设置此工具条
		webView.getSettings().setAppCacheEnabled(true);
		webView.getSettings().setLoadWithOverviewMode(isOverView);
		webView.getSettings().setUseWideViewPort(isOverView);
		webView.loadUrl(url);
	}

	/**
	 * 使用WebView加载url地址
	 * 
	 * @param context
	 *            视图上下文
	 * @param data
	 *            需加载的data
	 * @param webView
	 *            浏览器对像 支持javascript 支持放大缩小 显示放大缩小工具
	 */
	public static void loadData(Context context, String data, String mimeType,
			String encoding, WebView webView) {
		loadData(context, data, mimeType, encoding, webView, true, true, true);
	}

	/**
	 * 使用WebView加载url地址
	 * 
	 * @param context
	 *            视图上下文
	 * @param url
	 *            需访问的url
	 * @param webView
	 *            浏览器对像
	 * @param jsEnabled
	 *            浏览器是否支持javascript
	 * @param supportZoom
	 *            浏览器是否支持放大缩小
	 * @param zoomControls
	 *            浏览器是否显示放大缩小工具
	 */
	@SuppressLint("SetJavaScriptEnabled")
	public static void loadData(Context context, String data, String mimeType,
			String encoding, WebView webView, boolean jsEnabled,
			boolean supportZoom, boolean zoomControls) {
		webView.getSettings().setJavaScriptEnabled(jsEnabled);
		webView.getSettings().setSupportZoom(supportZoom);
		webView.getSettings().setBuiltInZoomControls(zoomControls);// 放大缩小工具条，如果屏幕支持多点触摸，则可以不设置此工具条
		webView.getSettings().setAppCacheEnabled(true);
		webView.loadDataWithBaseURL("", data, mimeType, encoding, "");
	}

	/** 加载数据进度视图布局 **/
	public static LinearLayout loadingLayout(Context context) {
		LinearLayout loadingLayout = new LinearLayout(context);
		loadingLayout.setGravity(Gravity.CENTER);
		ProgressBar progressBar = new ProgressBar(context);
		progressBar.setBackgroundColor(R.drawable.red);
		// 布局
		LayoutParams mLayoutParams = new LinearLayout.LayoutParams(
				LinearLayout.LayoutParams.WRAP_CONTENT,
				LinearLayout.LayoutParams.WRAP_CONTENT);

		loadingLayout.addView(progressBar, mLayoutParams);
		TextView loadingTV = new TextView(context);
		loadingTV.setLayoutParams(mLayoutParams);
		loadingTV.setText("正在加载更多...");
		loadingTV.setPadding(15, 0, 0, 0);
		loadingLayout.addView(loadingTV);
		loadingLayout.setVisibility(View.GONE);
		return loadingLayout;
	}

	/**
	 * 
	 * @param context
	 *            当前视图上下文
	 * @param currentPage
	 *            当前页
	 * @param totalPage
	 *            总页数
	 * @return 返回当面页/总页数的视图
	 */
	public static TextView pageNumTextView(Context context, int currentPage,
			int totalPage) {
		// 布局
		LayoutParams mLayoutParams = new LinearLayout.LayoutParams(
				LinearLayout.LayoutParams.WRAP_CONTENT,
				LinearLayout.LayoutParams.WRAP_CONTENT);
		TextView pageNumTextView = new TextView(context);
		pageNumTextView.setLayoutParams(mLayoutParams);
		pageNumTextView.setText(currentPage + "/" + totalPage + "页");

		return pageNumTextView;
	}

	/**
	 * 下载多张网络图片
	 * 
	 * @param urls
	 * @return 图片url及其Bitmap的集合
	 */
	public static LinkedHashMap<String, Bitmap> loadBitmap(List<String> urls) {
		final LinkedHashMap<String, Bitmap> map = new LinkedHashMap<String, Bitmap>();
		for (final String url : urls) {
			Bitmap bitmap = loadBitmap(url);
			if (null != bitmap)
				map.put(url, bitmap);
		}
		return map;
	}

	/**
	 * 下载多张网络图片
	 * 
	 * @param urls
	 * @return 图片url及其Bitmap的集合
	 */
	public static LinkedHashMap<String, Bitmap> loadBitmap(Set<String> urlSet) {
		final LinkedHashMap<String, Bitmap> map = new LinkedHashMap<String, Bitmap>();
		Iterator<String> it = urlSet.iterator();
		while (it.hasNext()) {
			String url = it.next();
			Bitmap bitmap = loadBitmap(url);
			if (null != bitmap)
				map.put(url, bitmap);
		}
		return map;
	}

	/** 加载网络图片，url要写绝对地址 **/
	public static Bitmap loadBitmap(String url) {
		Bitmap bitmap = null;
		Drawable drawable = AsyncImageLoader.getDrawableFromSoftRef(url);
		if (drawable != null) {// 如果缓存中包含此图则从缓存中获取
			bitmap = ((BitmapDrawable) drawable).getBitmap();
			return bitmap;
		}

		File imgCachePath = new File(Constant.IMG_CACHE_PATH);// 存放图片缓存的目录
		String imgCacheFileName = Constant.IMG_CACHE_PATH + getMD5String(url);
		try {
			if (!imgCachePath.exists()) {
				imgCachePath = FileUtilsByCCN
						.createDir(Constant.IMG_CACHE_PATH);
				setImgCacheContentLen(0L);
			} else if (isFirstTimeLoadBitmap) {
				// 第一次把目录下未下载完成的文件删除
				delINGCacheFile(Constant.IMG_CACHE_PATH);
				// 启动程序则只进行一次查找文件并计算缓存目录的占用的空间，
				// 在后续中增删缓存图片时直接对imgCacheContentLen进行加减以便提高机子的运行速度
				setImgCacheContentLen(FileUtilsByCCN
						.getFileContentLength(imgCachePath));
				deleteImgCacheFile();
				isFirstTimeLoadBitmap = false;
			}
			File imgCacheFile = new File(imgCacheFileName);
			InputStream in = null;
			boolean isExists = imgCacheFile.exists();
			if (isExists) {// 从sdcard的cache中获取
				// 每从sdcard中获取该文件，则修改imgCacheFile的最新时间，以便使其超时时间会更长
				try {
					imgCacheFile.setLastModified(System.currentTimeMillis());
					in = new FileInputStream(imgCacheFile);
					bitmap = getBitMapFromInputStream(in);
					// System.out.println("get bitmap from sdcard  size="+imgCacheFile.length()
					// +" url="+url);
				} catch (Exception e) {
					isExists = false;
					e.printStackTrace();
				}
			}
			if (!isExists) {// 如果sdcard中无缓存图片，则从服务器中下载
				in = getInputStream(url);
				bitmap = getBitMapFromInputStream(in);
				// System.out.println(" get bitmap from server  size="
				// +imgCacheFile.length() +" url="+url);
				if (null != bitmap) {
					drawable = new BitmapDrawable(bitmap);
					// 开启新线程，如果未达到最大空间限制，则直接保存在sdcard中，如果达到空间限制则删除过期的缓存图片文件，再保存在sdcar中
					saveImgCacheToSdcard(imgCacheFileName, bitmap);// 保存图片到sdcard中
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			bitmap = null;
		}
		if (null != bitmap) {
			drawable = new BitmapDrawable(bitmap);
			AsyncImageLoader.getImageCache().put(url,
					new SoftReference<Drawable>(drawable));// 把该图放入软引用内存缓存
		}
		return bitmap;
	}

	/**
	 * 
	 * @param cacheFilePath
	 *            缓存文件存放的目录
	 * @param maxCacheContentLen
	 *            最大的缓存空间
	 * @param currentCacheContentLen
	 *            当前缓存文件占用的空间大小
	 * @param delFileNum
	 *            一次最多删除最旧的缓存文件个数
	 * @param fileName
	 * @param bitmap
	 */
	private static void saveImgCacheToSdcard(final String fileName,
			final Bitmap bitmap) {
		new Thread() {
			public void run() {
				deleteImgCacheFile();
				saveBitmapToSdcard(fileName, bitmap);
			};
		}.start();
	}

	/**
	 * 一次最多删除最旧的缓存文件个数
	 */
	private synchronized static void deleteImgCacheFile() {
		if (getImgCacheContentLen() >= Constant.MAX_IMG_CACHE_STORAGE) {
			File imgCachePath = new File(Constant.IMG_CACHE_PATH);
			File[] fileArray = imgCachePath.listFiles();
			List<File> listFile = new ArrayList<File>();
			for (File file : fileArray) {
				listFile.add(file);
			}
			Collections.sort(listFile, new FileModifyTimeComparator());
			long oneM = 1024 * 1024;
			for (int i = 0; i < listFile.size(); i++) {
				if (getImgCacheContentLen() >= Constant.MAX_IMG_CACHE_STORAGE
						- oneM) {
					FileUtilsByCCN.deleteFile(listFile.get(i));
					setImgCacheContentLen(getImgCacheContentLen()
							- listFile.get(i).length());
					System.out
							.println((imgCacheContentLen - Constant.MAX_IMG_CACHE_STORAGE)
									+ " delete file "
									+ listFile.get(i).getName());
				}
			}
		}
	}

	/**
	 * 
	 * @param fileName
	 *            保存的文件路径名
	 * @param bitmap
	 *            需要保存的bitmap
	 */
	public static void saveBitmapToSdcard(String fileName, Bitmap bitmap) {
		try {
			String bakFileName = fileName + Constant.ING;
			File saveFile = FileUtilsByCCN.createFile(bakFileName);
			if (!saveFile.exists())
				return;
			BufferedOutputStream bos = new BufferedOutputStream(
					new FileOutputStream(saveFile));
			bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
			bos.flush();
			bos.close();
			File file = new File(fileName);
			if (file.exists())
				file.delete();
			saveFile.renameTo(file);
			setImgCacheContentLen(getImgCacheContentLen() + file.length());
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 
	 * @param in
	 *            输入流
	 * @return 把输入流转换成Bitmap
	 */
	private static Bitmap getBitMapFromInputStream(InputStream in) {
		if (null == in)
			return null;
		OutputStream out = null;
		ByteArrayOutputStream dataStream = null;
		final int IO_BUFFER_SIZE = 1024 * 4;
		Bitmap bitmap = null;
		try {
			dataStream = new ByteArrayOutputStream();
			out = new BufferedOutputStream(dataStream, IO_BUFFER_SIZE);
			byte[] buffer = new byte[IO_BUFFER_SIZE];
			int len = -1;
			while (-1 != (len = in.read(buffer))) {
				out.write(buffer, 0, len);
			}
			out.flush();
			dataStream.flush();
			final byte[] data = dataStream.toByteArray();
			BitmapFactory.Options options = new BitmapFactory.Options();
			options.inSampleSize = 1;// 图片高宽度都为原来的二分之一，即图片大小为原来的大小的四分之一
			options.inTempStorage = new byte[16 * 1024];// 设置16kb的临时存储空间（不过作用还没看出来，待验证）
			bitmap = BitmapFactory.decodeByteArray(data, 0, data.length,
					options);

		} catch (IOException e) {
			e.printStackTrace();
			bitmap = null;
		} finally {
			closeInputStream(in);
			closeOutputStream(dataStream);
			closeOutputStream(out);
		}
		return bitmap;
	}

	public static void closeInputStream(InputStream out) {
		if (null != out) {
			try {
				out.close();
				out = null;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public static void closeOutputStream(OutputStream out) {
		if (null != out) {
			try {
				out.close();
				out = null;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 按下这个按钮进行的颜色过滤
	 */
	public final static float[] BT_SELECTED = new float[] { 2, 0, 0, 0, 2, 0,
			2, 0, 0, 2, 0, 0, 2, 0, 2, 0, 0, 0, 1, 0 };

	/**
	 * 按钮恢复原状的颜色过滤
	 */
	public final static float[] BT_NOT_SELECTED = new float[] { 1, 0, 0, 0, 0,
			0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0 };

	/**
	 * 按钮焦点改变
	 */
	public final static OnFocusChangeListener buttonOnFocusChangeListener = new OnFocusChangeListener() {

		public void onFocusChange(View v, boolean hasFocus) {
			if (hasFocus) {
				v.getBackground().setColorFilter(
						new ColorMatrixColorFilter(BT_SELECTED));
				v.setBackgroundDrawable(v.getBackground());
			} else {
				v.getBackground().setColorFilter(
						new ColorMatrixColorFilter(BT_NOT_SELECTED));
				v.setBackgroundDrawable(v.getBackground());
			}
		}
	};

	/**
	 * 按钮触碰按下效果
	 */
	public final static OnTouchListener buttonOnTouchListener = new OnTouchListener() {
		public boolean onTouch(View v, MotionEvent event) {
			if (event.getAction() == MotionEvent.ACTION_DOWN) {
				v.getBackground().setColorFilter(
						new ColorMatrixColorFilter(BT_SELECTED));
				v.setBackgroundDrawable(v.getBackground());
			} else if (event.getAction() == MotionEvent.ACTION_UP) {
				v.getBackground().setColorFilter(
						new ColorMatrixColorFilter(BT_NOT_SELECTED));
				v.setBackgroundDrawable(v.getBackground());
			}
			return false;
		}
	};

	/**
	 * 设置图片按钮获取焦点改变状态,改变其背景颜色
	 * 
	 * @param inImageButton
	 */
	public static void setButtonFocusChanged(View inView) {
		inView.setOnTouchListener(buttonOnTouchListener);
		inView.setOnFocusChangeListener(buttonOnFocusChangeListener);
	}

	public String urlEncode(String src, String charset)
			throws UnsupportedEncodingException {
		if (null != src) {
			src = URLEncoder.encode(src, charset);
		}
		return src;
	}

	public static int getAndroidOSVersion() {
		return android.os.Build.VERSION.SDK_INT;
	}

	/** 获取本机应用的版本号 **/
	public static int getLocalVerCode(Context context) {
		int verCode = -1;
		try {
			verCode = context.getPackageManager().getPackageInfo(
					Constant.APP_PAKAGE, 0).versionCode;
		} catch (NameNotFoundException e) {
			e.printStackTrace();
		}
		return verCode;
	}

	/** 获取本机应用的版本名称 **/
	public static String getLocalVerName(Context context) {
		String verName = "";
		try {
			verName = context.getPackageManager().getPackageInfo(
					Constant.APP_PAKAGE, 0).versionName;
		} catch (NameNotFoundException e) {
			e.printStackTrace();
		}
		return verName;
	}

	/** 获取新的版本 **/
	public static Version getNewVewsion() {
		Version version = null;
		try {
			String gsonStr = getContent(Constant.CHECK_UPDATE_ACTION,
					Constant.CHARSET_GBK, false);
			version = new Gson().fromJson(gsonStr, Version.class);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return version;
	}
	
	/**获取自定义生成的app id号**/
	public static String getAppId(){
		String appId = null;
		File appIdFile = new File(Constant.APP_ID_FILE);
		try {
			if(appIdFile.exists()){
				appId = FileUtilsByCCN.readCharFile(appIdFile, true,false);//read from sdcard
			}
			if(null == appId || "".equals(appId.trim())){
				String uuid = getUUID();
				appId = getMD5String(uuid);
				FileUtilsByCCN.write2File(Constant.APP_ID_FILE, appId);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return appId;
	}
	/**用于后台统计app的使用情况**/
	public static void statVisit(final Context context) {
		new Thread() {
			public void run() {
				try {
					String appId = getAppId();
					String vsn = getLocalVerName(context);
					int vsc = getLocalVerCode(context);	
					String os = "SDK_INT:" + getAndroidOSVersion() + ",RELEASE:" + android.os.Build.VERSION.RELEASE;
					String url = Constant.STAT_VISIT_URL+"?appId="+appId+"&vsn="+vsn+"&vsc="+vsc+"&os="+os;
					System.out.println(url);
					getContent(url, Constant.CHARSET_GBK, false);
				} catch (IOException e) {
					e.printStackTrace();
				}
			};
		}.start();
	}

	/**
	 * 检测应用更新,并对检测结果进行提示
	 * 
	 * @param context
	 */
	public static void checkAppUpdate(final Context context,
			final boolean dialogIsShowNoNew) {
		boolean flag = checkNetWorkStatus((Activity) context, true);
		if (!flag)
			return;
		new AsyncTask<String, Integer, Version>() {
			@Override
			protected Version doInBackground(String... params) {
				return getNewVewsion();
			}

			@Override
			protected void onPostExecute(Version newVersion) {
				if (null == newVersion) {
					Toast.makeText(context, Constant.NET_ERROR,
							Toast.LENGTH_SHORT).show();
					return;
				}
				int newVersionCode = newVersion.getVersionCode();
				int localVersionCode = CommonUtil.getLocalVerCode(context);
				String localVersionName = CommonUtil.getLocalVerName(context);
				if (newVersionCode > localVersionCode) {// 提示有新版本更新
					doNewVersionUpdate(context, newVersion);
				} else if (dialogIsShowNoNew) {// 没有新版本更新
					noNewVersionShow(context, localVersionCode,
							localVersionName, newVersion);
				}
			}

		}.execute();
	}

	/** 没有新版本更新 **/
	public static void noNewVersionShow(Context context, int localVersionCode,
			String localVersionName, Version newVersion) {
		StringBuffer sb = new StringBuffer();
		sb.append("当前版本:");
		sb.append(localVersionName);
		// sb.append(" Code:");
		// sb.append(localVersionCode);
		sb.append(",\n已是最新版,无需更新!");
		Dialog dialog = new AlertDialog.Builder(context)
				.setTitle(newVersion.getAppName() + " 应用更新")
				.setMessage(sb.toString())// 设置内容
				.setPositiveButton("确定",// 设置确定按钮
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog,
									int which) {
								dialog.dismiss();
							}
						}).create();// 创建
		// 显示对话框
		dialog.show();
	}

	/** 提示有新版本更新 **/
	public static void doNewVersionUpdate(final Context context,
			final Version newVersion) {
		// int localVersionCode = CommonUtil.getLocalVerCode(context);
		String localVersionName = CommonUtil.getLocalVerName(context);
		StringBuffer sb = new StringBuffer();
		sb.append("当前版本:");
		sb.append(localVersionName);
		// sb.append(" Code:");
		// sb.append(localVersionCode);
		sb.append(",新版本:");
		// sb.append(newVersion.getVersionCode());
		// sb.append(" Code:");
		sb.append(newVersion.getVersionName()).append("\n");
		double length = newVersion.getContentLen();
		double size = length / (1024 * 1024);
		NumberFormat df = NumberFormat.getNumberInstance();
		df.setMaximumFractionDigits(2);// 进行四舍五入后取两位小数位
		sb.append("更新包大小:").append(df.format(size)).append("M");
		sb.append(", 是否更新?");
		sb.append("\n本次更新的主要内容:\n").append(newVersion.getDescription());
		Dialog dialog = new AlertDialog.Builder(context)
				.setTitle(newVersion.getAppName() + " 应用更新")
				.setMessage(sb.toString())
				// 设置内容
				.setPositiveButton("更新",// 设置确定按钮
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog,
									int which) {
								String url = newVersion.getApkName();
								Intent intent = new Intent(context,
										DownloadService.class);
								intent.putExtra("url", url);
								String saveFileNamePath = Constant.LOACL_APK_SAVE_PATH
										+ url.substring(url.lastIndexOf("/") + 1);
								intent.putExtra("saveFileNamePath",
										saveFileNamePath);
								context.startService(intent);// 启动下载service
							}
						})
				.setNegativeButton("暂不更新",
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog,
									int whichButton) {
								// 点击"取消"按钮之后退出程序
								dialog.dismiss();
							}
						}).create();// 创建
		// 显示对话框
		dialog.show();
	}

	/**
	 * 跳转下载APK [一句话功能简述]<BR>
	 * [功能详细描述]
	 * 
	 * @param apkUrl
	 */
	public static void jumpDownApk(Context context, String url) {

		if (url != null && !url.equals("")) {
			if (!url.startsWith("http://") && !url.startsWith("https://")) {
				url = "http://" + url;
			}
		}

		if (!URLUtil.isNetworkUrl(url)) {

			Log.e("error", "APK 下载地址不合法 :" + url);
			return;
		}

		context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
	}

	/** 安装apk应用程序 **/
	public static void installApk(Context context, String apkPathAndName) {
		Intent intent = new Intent(Intent.ACTION_VIEW);
		intent.setDataAndType(Uri.fromFile(new File(apkPathAndName)),
				"application/vnd.android.package-archive");
		context.startActivity(intent);
	}

	public static InputStream getInputStream(String httpUrl) throws IOException {
		URL url = new URL(httpUrl);
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		conn.setConnectTimeout(2500);
		conn.setRequestMethod("GET");
		conn.setDoInput(true);
		conn.connect();
		return conn.getInputStream();
	}

	public static InputStreamReader getInputStreamReader(String httpUrl,
			String charset) throws IOException {
		return new InputStreamReader(getInputStream(httpUrl), charset);
	}

	/**
	 * 删除未完成下载的文件
	 * 
	 * @param filePath
	 */
	private static void delINGCacheFile(String filePath) {
		File[] delFiles = FileUtilsByCCN.listFiles(filePath, Constant.ING);
		if (null != delFiles) {
			for (File delFile : delFiles) {
				FileUtilsByCCN.deleteFile(delFile);
			}
		}
	}

	/**
	 * @param httpUrl
	 * @param charset
	 * @param isOpenCache
	 *            是否开启本地sdcard缓存
	 * @return 获取远程服务的文本内容
	 * @throws IOException
	 */
	public static String getContent(String httpUrl, String charset,
			boolean isOpenCache) throws IOException {
		StringBuffer sb = new StringBuffer();
		File textCachePath = FileUtilsByCCN.createDir(Constant.TXT_CACHE_PATH);
		if (isFirstTimeLoadTxt) {
			// 第一次把目录下未下载完成的文件删除
			delINGCacheFile(Constant.TXT_CACHE_PATH);
			setTxtCacheContentLen(FileUtilsByCCN
					.getFileContentLength(textCachePath));
			isFirstTimeLoadTxt = false;
		}
		final String fileName = Constant.TXT_CACHE_PATH + getMD5String(httpUrl);
		File textCacheFile = new File(fileName);
		boolean isTextCacheExit = textCacheFile.exists();
		InputStreamReader isr = null;
		if (isTextCacheExit && isOpenCache) {
			try {
				System.out
						.println("get from sdcard " + textCacheFile.getName());
				isr = new InputStreamReader(new FileInputStream(textCacheFile),
						charset);
			} catch (Exception e) {
				isTextCacheExit = false;
				e.printStackTrace();
			}
		}
		if (!isTextCacheExit || !isOpenCache) {
			System.out.println("get from server httpUrl=" + httpUrl);
			isr = getInputStreamReader(httpUrl, charset);
			textCacheFile = FileUtilsByCCN.createFile(fileName);
		}
		BufferedReader br = new BufferedReader(isr);
		String line = null;
		while (null != (line = br.readLine())) {
			sb.append(line).append(Constant.NEW_LINE);
		}
		isr.close();
		isr = null;
		if (!isTextCacheExit && textCacheFile.exists() && isOpenCache) {
			deleteTxtCacheFile();
			ByteArrayInputStream inStream = new ByteArrayInputStream(sb
					.toString().getBytes(charset));
			saveCacheToSdcard(fileName, inStream, new ISaveCache() {
				@Override
				public void deal() {
					setTxtCacheContentLen(getTxtCacheContentLen()
							+ FileUtilsByCCN.getFileContentLength(new File(
									fileName)));
				}
			});
		}

		return sb.toString();
	}

	/**
	 * 
	 * @param fileName
	 *            保存的缓存文件路径名
	 * @param in
	 *            需要保存的inputstream内容
	 * @param currentCacheContentLen
	 *            当前缓存文件占用的空间大小
	 */
	public static void saveCacheToSdcard(String fileName, InputStream in,
			ISaveCache iSavaCache) {
		try {
			String bakFileName = fileName + Constant.ING;
			File saveFile = FileUtilsByCCN.createFile(bakFileName);
			if (!saveFile.exists())
				return;
			BufferedOutputStream bos = new BufferedOutputStream(
					new FileOutputStream(saveFile));
			byte[] buffer = new byte[1024 * 4];
			int len = -1;
			while (-1 != (len = in.read(buffer))) {
				bos.write(buffer, 0, len);
			}
			bos.flush();
			bos.close();
			File file = new File(fileName);
			if (file.exists())
				file.delete();
			saveFile.renameTo(file);
			iSavaCache.deal();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 一次最多删除最旧的缓存文件个数
	 */
	private synchronized static void deleteTxtCacheFile() {
		if (getTxtCacheContentLen() >= Constant.MAX_TXT_CACHE_STORAGE) {
			File txtCachePath = new File(Constant.TXT_CACHE_PATH);
			File[] fileArray = txtCachePath.listFiles();
			List<File> listFile = new ArrayList<File>();
			for (File file : fileArray) {
				listFile.add(file);
			}
			Collections.sort(listFile, new FileModifyTimeComparator());
			long oneM = 1024 * 1024;
			for (int i = 0; i < listFile.size(); i++) {
				if (getImgCacheContentLen() >= Constant.MAX_TXT_CACHE_STORAGE
						- oneM) {
					FileUtilsByCCN.deleteFile(listFile.get(i));
					setImgCacheContentLen(getImgCacheContentLen()
							- listFile.get(i).length());
					System.out
							.println((getTxtCacheContentLen() - Constant.MAX_TXT_CACHE_STORAGE)
									+ " delete file "
									+ listFile.get(i).getName());
				}
			}
		}
	}

	/**
	 * 跳转到剪切图片功能视图
	 * 
	 * @param activity
	 *            当前视图
	 * @param _captureUri
	 *            需要剪切的图片Uri地址
	 */
	public static void startToCropImage(Activity activity, Uri _captureUri) {
		try {
			final List<CropOption> cropOptions = new ArrayList<CropOption>();
			// this 2 lines are all you need to find the intent!!!
			Intent intent = new Intent("com.android.camera.action.CROP");// 系统自带剪切图片功能
			intent.setType("image/*");
			PackageManager packageManager = activity.getPackageManager();
			List<ResolveInfo> list = packageManager.queryIntentActivities(
					intent, 0);
			if (list.size() == 0)
				return;
			intent.setData(_captureUri);
			intent.putExtra("outputX", 128);
			intent.putExtra("outputY", 128);
			intent.putExtra("aspectX", 1);
			intent.putExtra("aspectY", 1);
			intent.putExtra("scale", true);
			intent.putExtra("return-data", true);
			for (ResolveInfo res : list) {
				CropOption co = new CropOption();
				co.TITLE = packageManager
						.getApplicationLabel(res.activityInfo.applicationInfo);
				co.ICON = packageManager
						.getApplicationIcon(res.activityInfo.applicationInfo);
				co.CROP_APP_INTENT = new Intent(intent);
				co.CROP_APP_INTENT.setComponent(new ComponentName(
						res.activityInfo.packageName, res.activityInfo.name));
				cropOptions.add(co);
			}
			activity.startActivityForResult(cropOptions.get(0).CROP_APP_INTENT,
					Constant.CROP_REQUEST_CODE);
		} catch (Exception ex) {
			Log.e("ex", "processing capture", ex);
		}
	}

	/**
	 * 把一个图片相对路径变成绝对数径，例如： "img1/pic/201108/356.jpg" ==>
	 * "http://img1.taojindi.com/pic/201108/356.jpg"
	 * 
	 * @param path
	 *            图片相对路径
	 * @return 转换后的绝对路径
	 */
	public static String getResPath(String path) {
		String domain = "http://{0}.taojindi.com";
		if (path == null)
			return null;
		int pos = path.indexOf('/');
		if (pos < 1) // 路径没有斜线或以斜线打头，直接返回路径
			return path;
		String server = path.substring(0, pos);
		return domain.replace("{0}", server) + path.substring(pos);
	}

	public static String getResPath(String path, String picSize) {
		if (path == null)
			return null;
		String domain = "http://{0}.taojindi.com";
		int pos1 = path.indexOf('/');
		if (pos1 < 1) // 路径中没有斜线或以斜线打头，直接返回路径
			return path;
		String server = path.substring(0, pos1);
		int pos2 = path.indexOf('/', pos1 + 1); // 找第二个斜线的位置
		if (pos2 < 1) {
			return path;
		}
		return domain.replace("{0}", server) + path.substring(pos1, pos2 + 1)
				+ picSize + path.substring(pos2);
	}

	public static String getUUID(){
		UUID uuid = UUID.randomUUID();
		return uuid.toString();
	}
	
	/**
	 * 
	 * @param inStr
	 *            需要加密的字符串
	 * @return MD5加密后的字符串
	 */
	public static String getMD5String(String inStr) {
		MessageDigest md5 = null;
		try {
			md5 = MessageDigest.getInstance("MD5");
		} catch (Exception e) {
			e.printStackTrace();
			return "";
		}
		char[] charArray = inStr.toCharArray();
		byte[] byteArray = new byte[charArray.length];

		for (int i = 0; i < charArray.length; i++)
			byteArray[i] = (byte) charArray[i];

		byte[] md5Bytes = md5.digest(byteArray);

		StringBuffer hexValue = new StringBuffer();

		for (int i = 0; i < md5Bytes.length; i++) {
			int val = ((int) md5Bytes[i]) & 0xff;
			if (val < 16)
				hexValue.append("0");
			hexValue.append(Integer.toHexString(val));
		}

		return hexValue.toString();
	}

	public synchronized static long getImgCacheContentLen() {
		return imgCacheContentLen;
	}

	public synchronized static void setImgCacheContentLen(
			long imgCacheContentLen) {
		CommonUtil.imgCacheContentLen = imgCacheContentLen;
	}

	public synchronized static long getTxtCacheContentLen() {
		return txtCacheContentLen;
	}

	public synchronized static void setTxtCacheContentLen(
			long txtCacheContentLen) {
		CommonUtil.txtCacheContentLen = txtCacheContentLen;
	}

	public interface ISaveCache {
		public void deal();
	}
}
